//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;

using System.IdentityModel.Claims;
using System.IdentityModel.Policy;

namespace EAI.SAML
{
    class UnconditionalPolicy : IAuthorizationPolicy
    {
        static IIdentity AnonymousIdentity = new GenericIdentity(String.Empty);

        ClaimSet issuerClaimset;
        List<ClaimSet> issuances;
        IIdentity identity;

        public UnconditionalPolicy(IIdentity identity, ClaimSet issuerClaimset, IEnumerable<ClaimSet> issuances)
        {
            this.identity = identity;
            this.issuerClaimset = issuerClaimset;
            foreach (ClaimSet issuance in issuances)
            {
                if (this.issuances == null)
                    this.issuances = new List<ClaimSet>();
                this.issuances.Add(issuance);
            }
        }

        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        {
            if (this.issuerClaimset != null)
            {
                evaluationContext.AddClaimSet(this, this.issuerClaimset);
            }
            else
            {
                foreach (ClaimSet claimSet in this.issuances)
                    evaluationContext.AddClaimSet(this, claimSet);
            }

            if (this.PrimaryIdentity != null && this.PrimaryIdentity != AnonymousIdentity)
            {
                IList<IIdentity> identities;
                object obj;
                if (!evaluationContext.Properties.TryGetValue("Identities", out obj))
                {
                    identities = new List<IIdentity>(1);
                    evaluationContext.Properties.Add("Identities", identities);
                }
                else
                {
                    // null if other overrides the property with something else
                    identities = obj as IList<IIdentity>;
                }

                if (identities != null)
                {
                    identities.Add(this.PrimaryIdentity);
                }
            }

            evaluationContext.RecordExpirationTime(DateTime.Now.ToUniversalTime());
            return true;
        }

        public ClaimSet Issuer
        {
            get { return this.issuerClaimset; }
        }

        public IList<ClaimSet> Issuances
        {
            get { return this.issuances; }
        }

        public IIdentity PrimaryIdentity
        {
            get { return this.identity; }
        }

        public string Id
        {
            get { return Guid.NewGuid().ToString(); }
        }
    }
}
